using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using LitJson;
using DICE_GS;
using TwoStepsAuthenticator;

public enum RestAPIProtocol
{
    CREATEUSER,
    GETSERVERUNIXTIME,
    PUTUSERDATA,
    GETNORMALGACHAINFO,
    GETCASHGACHAINFO,
    GETMYUNITLIST,
    SENDUNITCOMPOSERESULT,
    SENDUNITEVOLUTIONRESULT,
    BUYSHOPITEM,
    GETUSERRANKINGLIST,
    REFRESHUSERINFO,
    REFRESHMYDECKINFO,
    SENDFACEBOOKINFO,
    SENDMYDECKCHANGEINFO,
    GETMYFRIENDLIST,
    GETMYFRIENDREQUESTLIST,
    SENDFRIENDREQUEST,
    ACCEPTFRIENDREQUEST,
    DENYFRIENDREQUEST,
    DELETEFRIEND,
    SENDFACEBOOKAPPREQUESTINFO,
    SENDREFERRALINFO,
    GETMYMAILBOXLIST,
    SENDMAIL,
    ACCETPMAIL,
    DELETEMAIL,
    GETCURRENTSTAMINAINFO,
    SELLUNITCARD,
    GETMYSKILLLIST,
    GETMYCHARACTERLIST,
    SETCURRENTCHARACTER,
    SENDDEVICEPUSHTOKEN,
    GETMYACHIEVEMENTLIST,
    GETMYACHIEVEMENTREWARD,
    GETMYACHIEVEMENTVALUE,
    GETPVESTAGEINFO,
};

public enum STATUS
{
    Success,
    Fail,
};

public delegate void RestAPIReturnCallback(Hashtable returnData);

public class RestAPI : MonoBehaviour
{
    static RestAPI _singleton;

    public static RestAPI singleton
    {
        get { return _singleton; }
        set { _singleton = value; }
    }

    private bool _isDebugMode = false;
    public bool debugMode
    {
        get { return _isDebugMode; }
        set { _isDebugMode = value; }
    }

    private object thisLock = new object();
    private int sequenceNumber = 0;

    private string target
    {
        get
        {
            if (CSceneManager.BuildType == 1)
                return "211.189.163.179/dice_deploy/api"; //QA
            else if (CSceneManager.BuildType == 0)
                return "211.189.163.178/dice_deploy/api"; //DEV
            else if (CSceneManager.BuildType == 2)
                return PlayerPrefs.GetString("CustomGameServerAddress") + "/dice_deploy/api";
            else
                return "211.189.163.178/dice_deploy/api"; //DEV
        }
    }

    private System.TimeSpan span = new System.TimeSpan(0, 0, 0, 45, 0);

    // Use this for initialization
    void Awake()
    {
        Debug.LogError(target);
        DontDestroyOnLoad(gameObject);
        if (RestAPI.singleton == null)
            RestAPI.singleton = this;
    }


    public int CreateUser(RestAPIReturnCallback callback, string name, int pawnIndex)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            sendData.Add("DeviceId", SystemInfo.deviceUniqueIdentifier);
            sendData.Add("Name", name);
            sendData.Add("Pawn", pawnIndex);

            //StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.POST, sequenceNumber, target + "/user2", RestAPIProtocol.CREATEUSER, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int GetServerUnixTime(RestAPIReturnCallback callback)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            //			StringBuilder builder = new StringBuilder();
            //			builder.Append("?pid="+LCSocialPlatform.myUserInfo.userId);

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.GET, sequenceNumber, target + "/user", RestAPIProtocol.GETSERVERUNIXTIME, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int SendFacebookInfo(RestAPIReturnCallback callback, bool isforce)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            sendData.Add("FacebookToken", FB.AccessToken);
            sendData.Add("FacebookId", FB.UserId);
            sendData.Add("UpdateNewDevice", isforce);

            //StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.POST, sequenceNumber, target + "/Facebook/", RestAPIProtocol.SENDFACEBOOKINFO, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int PutUserData(RestAPIReturnCallback callback)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            sendData.Add("Id", MyInfo.Instance.DBID);
            sendData.Add("DeviceId", SystemInfo.deviceUniqueIdentifier);
            sendData.Add("Name", MyInfo.Instance.NickName);
            sendData.Add("Level", MyInfo.Instance.userLevel);
            sendData.Add("HpPotion", MyInfo.Instance.HPPotion);
            sendData.Add("ResurrectPotion", MyInfo.Instance.ResurrectPotion);
            sendData.Add("Stamina", MyInfo.Instance.Stamina);
            sendData.Add("Money", MyInfo.Instance.Money);
            sendData.Add("Diamond", MyInfo.Instance.Diamond);
            sendData.Add("FacebookId", FB.UserId);
            sendData.Add("InventoryExtend", MyInfo.Instance.AdditionalInvenCount);
            sendData.Add("Exp", MyInfo.Instance.Exp);
            sendData.Add("Score", MyInfo.Instance.Score);
            sendData.Add("LastLogin", DateTime.Parse(MyInfo.Instance.LastLoginTime));
            sendData.Add("Leader", MyInfo.Instance.MyDeckMap[MyInfo.Instance.MyCurrentDeck].SlotMap[0].UnitDBID);
            sendData.Add("Pawn", MyInfo.Instance.pawnId);
            sendData.Add("GachaPoint", MyInfo.Instance.gachaPoint);
            sendData.Add("GachaTicket", MyInfo.Instance.gachaTicket);

            //			StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.PUT, sequenceNumber, target + "/User2", RestAPIProtocol.PUTUSERDATA, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int RefreshUserData(RestAPIReturnCallback callback)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            //StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.GET, sequenceNumber, target + "/user2", RestAPIProtocol.REFRESHUSERINFO, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int RefreshMyDeckInfo(RestAPIReturnCallback callback)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            //StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.GET, sequenceNumber, target + "/deck2", RestAPIProtocol.REFRESHMYDECKINFO, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int SendMyDeckChangeInfo(RestAPIReturnCallback callback, int deckId)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            DeckInfo currentDeckInfo = new DeckInfo();
            foreach (KeyValuePair<int, DeckInfo> pair in MyInfo.Instance.MyDeckMap)
            {
                if (pair.Value.deckId == deckId)
                {
                    currentDeckInfo = pair.Value;
                    break;
                }
            }

            //int selectedSlotIndex = MyInfo.Instance.LastSeletedUnitSlot;		
            sendData.Add("Id", currentDeckInfo.deckId);
            sendData.Add("Order", currentDeckInfo.order);
            sendData.Add("UserId", MyInfo.Instance.DBID);
            sendData.Add("Skill1", currentDeckInfo.skill1);
            sendData.Add("SKill2", currentDeckInfo.skill2);
            sendData.Add("Leader", currentDeckInfo.SlotMap[0].UnitDBID);
            sendData.Add("Sub1", currentDeckInfo.SlotMap[1].UnitDBID);
            sendData.Add("Sub2", currentDeckInfo.SlotMap[2].UnitDBID);
            sendData.Add("Sub3", currentDeckInfo.SlotMap[3].UnitDBID);
            sendData.Add("Sub4", currentDeckInfo.SlotMap[4].UnitDBID);

            //			if( selectedSlotIndex == 0 && MyInfo.Instance.LastSelectedUnitDBID == 0 )
            //			{
            //				Debug.LogError("no Select unit for leader");
            //				sendData.Remove("Leader");
            //				sendData.Add("Leader", 0);
            //			}
            //			else if( selectedSlotIndex == 1 && MyInfo.Instance.LastSelectedUnitDBID == 0 )
            //			{
            //				sendData.Remove("Sub1");
            //				sendData.Add("Sub1", 0);
            //			}
            //			else if( selectedSlotIndex == 2 && MyInfo.Instance.LastSelectedUnitDBID == 0 )
            //			{
            //				sendData.Remove("Sub2");
            //				sendData.Add("Sub2", 0);
            //			}
            //			else if( selectedSlotIndex == 3 && MyInfo.Instance.LastSelectedUnitDBID == 0 )
            //			{
            //				sendData.Remove("Sub3");
            //				sendData.Add("Sub3", 0);
            //			}
            //			else if( selectedSlotIndex == 4 && MyInfo.Instance.LastSelectedUnitDBID == 0 )
            //			{
            //				sendData.Remove("Sub4");
            //				sendData.Add("Sub4", 0);
            //			}

            //            StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.PUT, sequenceNumber, target + "/deck2?id=" + deckId, RestAPIProtocol.SENDMYDECKCHANGEINFO, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int DeleteUnit(RestAPIReturnCallback callback)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            //StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.DELETE, sequenceNumber, target + "/Unit?Id =" + MyInfo.Instance.LastSelectedUnitDBID, RestAPIProtocol.GETSERVERUNIXTIME, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int GetNormalGachaInfo(RestAPIReturnCallback callback)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            //StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.GET, sequenceNumber, target + "/Gacha/NormalGacha", RestAPIProtocol.GETNORMALGACHAINFO, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int GetCashGachaInfo(RestAPIReturnCallback callback)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            //StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.GET, sequenceNumber, target + "/Gacha/CashGacha", RestAPIProtocol.GETCASHGACHAINFO, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int GetMyUnitList(RestAPIReturnCallback callback)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            //StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.GET, sequenceNumber, target + "/unit2", RestAPIProtocol.GETMYUNITLIST, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int SendUnitComposeResult(RestAPIReturnCallback callback, int originalCardId, List<int> materialUnitList)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            sendData.Add("userId", MyInfo.Instance.DBID);
            sendData.Add("Target", originalCardId);
            for (int i = 0; i < materialUnitList.Count; i++)
            {
                sendData.Add("Source" + (i + 1), materialUnitList[i]);
            }

            //			StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.POST, sequenceNumber, target + "/compose", RestAPIProtocol.SENDUNITCOMPOSERESULT, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int SendUnitEvolutionResult(RestAPIReturnCallback callback, int targetUnitId, List<UnitInfo> materialUnitList)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            sendData.Add("userId", MyInfo.Instance.DBID);
            sendData.Add("TargetId", targetUnitId);
            for (int i = 0; i < materialUnitList.Count; i++)
            {
                Debug.LogError("materialUnitList = " + i + "  /  " + materialUnitList[i].UnitDBID);

                sendData.Add("Source" + (i + 1), materialUnitList[i].UnitDBID);
            }

            //			StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.POST, sequenceNumber, target + "/evolution", RestAPIProtocol.SENDUNITCOMPOSERESULT, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int BuyShopItem(RestAPIReturnCallback callback, int ItemId)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            Debug.LogError(ItemId);

            sendData.Add("UserId", MyInfo.Instance.DBID);
            sendData.Add("ShopId", ItemId);

            //            StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.POST, sequenceNumber, target + "/Shop", RestAPIProtocol.BUYSHOPITEM, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int GetUserRankingList(RestAPIReturnCallback callback, int pageNum)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            //StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.GET, sequenceNumber, target + "/Rank?page=" + pageNum, RestAPIProtocol.GETUSERRANKINGLIST, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int GetMyFriendList(RestAPIReturnCallback callback)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            //StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.GET, sequenceNumber, target + "/friend/friendlist", RestAPIProtocol.GETMYFRIENDLIST, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int GetMyFriendRequestList(RestAPIReturnCallback callback)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            //StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.GET, sequenceNumber, target + "/friend/requestlist", RestAPIProtocol.GETMYFRIENDREQUESTLIST, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int SendFriendRequest(RestAPIReturnCallback callback, string friendName)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            //StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.GET, sequenceNumber, target + "/friend/request?name=" + friendName, RestAPIProtocol.SENDFRIENDREQUEST, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int AcceptFriendRequest(RestAPIReturnCallback callback, string friendName)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            //StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.GET, sequenceNumber, target + "/friend/accept?name=" + friendName, RestAPIProtocol.ACCEPTFRIENDREQUEST, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int DenyFriendRequest(RestAPIReturnCallback callback, string friendName)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            //StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.GET, sequenceNumber, target + "/friend/deny?name=" + friendName, RestAPIProtocol.DENYFRIENDREQUEST, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int DeleteFriend(RestAPIReturnCallback callback, string friendName)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            //StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.GET, sequenceNumber, target + "/friend/delete?name=" + friendName, RestAPIProtocol.DELETEFRIEND, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int SendFacebookAppRequestInfo(RestAPIReturnCallback callback, string userId)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            sendData.Add("FacebookUserId", userId);

            //StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.POST, sequenceNumber, target + "/facebookinvite", RestAPIProtocol.SENDFACEBOOKAPPREQUESTINFO, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int SendReferralInfo(RestAPIReturnCallback callback, string userName)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            sendData.Add("Referee", userName);

            //StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.POST, sequenceNumber, target + "/referral", RestAPIProtocol.SENDREFERRALINFO, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int GetMyMailboxList(RestAPIReturnCallback callback, int pageNum)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            //StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.GET, sequenceNumber, target + "/mail?page=" + pageNum, RestAPIProtocol.GETMYMAILBOXLIST, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int SendMail(RestAPIReturnCallback callback, string receiverName, string title, string content = "")
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            sendData.Add("Name", receiverName);
            sendData.Add("Title", title);
            sendData.Add("Content", content);

            //            StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.POST, sequenceNumber, target + "/mail", RestAPIProtocol.SENDMAIL, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int DeleteMail(RestAPIReturnCallback callback, int mailId)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            //StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.DELETE, sequenceNumber, target + "/mail?id=" + mailId, RestAPIProtocol.DELETEMAIL, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int AcceptMail(RestAPIReturnCallback callback, int mailId)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            //StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.GET, sequenceNumber, target + "/mail?id=" + mailId, RestAPIProtocol.ACCETPMAIL, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int GetCurrentStaminaInfo(RestAPIReturnCallback callback)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            //StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.GET, sequenceNumber, target + "/stamina", RestAPIProtocol.GETCURRENTSTAMINAINFO, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int GetMySkillList(RestAPIReturnCallback callback)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            //StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.GET, sequenceNumber, target + "/skill", RestAPIProtocol.GETMYSKILLLIST, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int GetMyCharacterList(RestAPIReturnCallback callback)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            //StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.GET, sequenceNumber, target + "/character", RestAPIProtocol.GETMYCHARACTERLIST, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int SetCurrentCharacter(RestAPIReturnCallback callback, int characterId)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            sendData.Add("characterId", characterId);

            //StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.POST, sequenceNumber, target + "/character", RestAPIProtocol.SETCURRENTCHARACTER, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int SellUnitCard(RestAPIReturnCallback callback, int unitId)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            //StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.DELETE, sequenceNumber, target + "/unit2?id=" + unitId, RestAPIProtocol.SELLUNITCARD, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int SendDevicePushToken(RestAPIReturnCallback callback, string token)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            sendData.Add("PushId", token);
            if (Application.platform == RuntimePlatform.IPhonePlayer)
                sendData.Add("os", "iOS");
            else if (Application.platform == RuntimePlatform.Android)
                sendData.Add("os", "Android");

            //StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.POST, sequenceNumber, target + "/PushToken", RestAPIProtocol.SENDDEVICEPUSHTOKEN, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int GetMyAchievementList(RestAPIReturnCallback callback)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            //StringBuilder builder = new StringBuilder();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.GET, sequenceNumber, target + "/achievement", RestAPIProtocol.GETMYACHIEVEMENTLIST, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int GetMyAchievementReward(RestAPIReturnCallback callback, int achievementId)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            sendData.Add("achievementId", achievementId);

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.POST, sequenceNumber, target + "/achievementreward", RestAPIProtocol.GETMYACHIEVEMENTREWARD, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int GetMyAchievementValue(RestAPIReturnCallback callback)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.GET, sequenceNumber, target + "/achievementvalue", RestAPIProtocol.GETMYACHIEVEMENTVALUE, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    public int GetPVEStageInfo(RestAPIReturnCallback callback)
    {
        int sequenceNumber;
        lock (thisLock)
        {
            sequenceNumber = ++this.sequenceNumber;
        }

        if (!_isDebugMode)
        {
            Hashtable sendData = new Hashtable();
            Hashtable header = new Hashtable();

            StartCoroutine(CallRestAPIByHTTP(callback, LC_WWW.HTTPMETHOD.GET, sequenceNumber, target + "/Stage", RestAPIProtocol.GETPVESTAGEINFO, sendData, header));
        }
        else
        {

        }

        return sequenceNumber;
    }

    private LC_WWW lc_www = null;
    private IEnumerator CallRestAPIByHTTP(RestAPIReturnCallback callback, LC_WWW.HTTPMETHOD method, int sequenceNumber, string url, RestAPIProtocol bodProtocol, Hashtable parameters, Hashtable header)
    {
        LoadingWindow.window.ShowShortLoading();
        lc_www = new LC_WWW(url);

        lc_www.Method = method;
        lc_www.Parameters = parameters;
        Authenticator auth = new Authenticator();
        //		header.Add("di", "A4CF2290-4C94-4CB8-8F37-DA96C72705B8");
        //		header.Add("di", "fc01d789841ed7842875f64988cf2e9bd6882cd3");
        //		header.Add("di", "A4CF2290-4C94-4CB8-8F37-DA96C72705B8");
        //		header.Add("di", "7e91ec19b53511d60732c0f0e0078c34724aa473");
        header.Add("ui", MyInfo.Instance.DBID);
        header.Add("di", SystemInfo.deviceUniqueIdentifier);
        header.Add("Au", auth.GetCode(null, SystemInfo.deviceUniqueIdentifier));
        //		header.Add("Au", auth.GetCode(null, "fc01d789841ed7842875f64988cf2e9bd6882cd3"));
        //		header.Add("Au", auth.GetCode(null, "A4CF2290-4C94-4CB8-8F37-DA96C72705B8"));
        //		header.Add("Au", auth.GetCode(null, "7e91ec19b53511d60732c0f0e0078c34724aa473"));
        //		header.Add("Au", "723458");
        if (FB.AccessToken != null)
            header.Add("ft", FB.AccessToken);
        else
            header.Add("ft", "");
        if (FB.UserId != null)
            header.Add("fi", FB.UserId);
        else
            header.Add("fi", "");

        lc_www.RequestHeaders = header;

        yield return StartCoroutine(GetRestApiReturnData(callback, sequenceNumber, lc_www, bodProtocol));
    }

    private IEnumerator GetRestApiReturnData(RestAPIReturnCallback callback, int sequenceNumber, LC_WWW lc_www, RestAPIProtocol bodProtocol)
    {
        yield return null;
        Hashtable returnData = new Hashtable();
        returnData.Add("protocol", bodProtocol);
        Debug.Log(Application.internetReachability);
        switch (Application.internetReachability)
        {
            case NetworkReachability.ReachableViaCarrierDataNetwork:
            case NetworkReachability.ReachableViaLocalAreaNetwork:
                lc_www.Send();

                System.DateTime time = System.DateTime.UtcNow;

                bool timeOver = false;

                while (!lc_www.IsDone)
                {
                    yield return null;

                    if ((System.DateTime.UtcNow - time) > span)
                    {
                        timeOver = true;
                        break;
                    }
                }


                if (timeOver)
                {
                    returnData.Add("error", "TimeOver");
                    returnData.Add("status", lc_www.Status.ToString());
                    Debug.LogError(lc_www.error);
                }
                else if (lc_www.Status >= 200 && lc_www.Status <= 299)
                {
                    if (!string.IsNullOrEmpty(lc_www.text))
                        returnData = ParsingServerData(lc_www.text, bodProtocol);
                }
                else if (lc_www.Status > 300 && lc_www.Status < 500)
                {
                    if (bodProtocol == RestAPIProtocol.SENDDEVICEPUSHTOKEN)
                    {
                        if (lc_www.Status == 409)
                        {
                        }
                    }
                    else if (bodProtocol == RestAPIProtocol.CREATEUSER)
                    {
                        if (lc_www.Status == 409)
                        {
                            returnData.Add("status", lc_www.Status);
                        }
                    }
                    else if (bodProtocol == RestAPIProtocol.SENDFACEBOOKINFO)
                    {
                        if (lc_www.Status == 409)
                        {
                            string[] param = new string[1];
                            MessagePopup.window.ShowPopup(MESSAGEPOPUPTYPE.FacebookConnect, param, CSceneManager.manager.MessagePopupCallback);
                            //                        CommonMsgBox.window.ShowPopup(PopupTypes.FacebookConnectionSelect, null);
                        }
                    }
                    else if (bodProtocol == RestAPIProtocol.SENDFRIENDREQUEST)
                    {
                        if (lc_www.Status == 402)
                        {
                            //already exist in friendlist
                            returnData.Add("status", lc_www.Status);
                        }
                    }
                    else if (bodProtocol == RestAPIProtocol.SENDFACEBOOKAPPREQUESTINFO)
                    {
                        if (lc_www.Status == 409)
                        {
                            //already accept gift
                            returnData.Add("status", lc_www.Status);
                        }
                    }
                    else if (bodProtocol == RestAPIProtocol.SENDREFERRALINFO)
                    {
                        if (lc_www.Status == 409)
                        {
                            //already exist referee info
                            returnData.Add("status", lc_www.Status);
                        }
                    }
                    else
                    {
                        returnData.Add("error", "server error!! Please Check it!");
                        returnData.Add("status", lc_www.Status);
                    }
                }
                else if (lc_www.Status == 500)
                {
                    returnData.Add("error", "Internal Server Error");
                }
                break;
        }

        if (!returnData.ContainsKey("error"))
        {
            if (callback.Target != null)
                callback(returnData);
        }
        //        else
        //        {
        //            Debug.LogError("Rest Error! - " + returnData["error"].ToString());
        //        }
        LoadingWindow.window.HideLoading();
    }


    private IEnumerator GetRestApiReturnData(RestAPIReturnCallback callback, int sequenceNumber, string url, LC_WWW.HTTPMETHOD method, WWWForm form, RestAPIProtocol bodProtocol)
    {
        yield return null;
        Hashtable returnData = new Hashtable();
        returnData.Add("protocol", bodProtocol);
        NetworkReachability networkStatus = NetworkReachability.NotReachable;
        if (Application.platform == RuntimePlatform.Android)
        {
            //			int status = LCPlatform.AndroidCheckNetworkStatus();
            //			if( status == 0 )
            //				networkStatus = NetworkReachability.NotReachable;
            //			else if( status == 1 )
            //				networkStatus = NetworkReachability.ReachableViaLocalAreaNetwork;
            //			else if( status == 2 )
            //				networkStatus = NetworkReachability.ReachableViaCarrierDataNetwork;
        }
        else
        {
            networkStatus = Application.internetReachability;
        }

        switch (networkStatus)
        {
            case NetworkReachability.ReachableViaCarrierDataNetwork:
            case NetworkReachability.ReachableViaLocalAreaNetwork:
#if UNITY_IPHONE
			url = System.Uri.EscapeUriString(url);
#endif
                WWW lc_www;
                if (method == LC_WWW.HTTPMETHOD.GET)
                    lc_www = new WWW(url);
                else
                    lc_www = new WWW(url, form);

                System.DateTime time = System.DateTime.UtcNow;

                bool timeOver = false;

                while (!lc_www.isDone)
                {
                    yield return null;

                    if ((System.DateTime.UtcNow - time) > span)
                    {
                        timeOver = true;
                        break;
                    }
                }

                if (timeOver)
                {
                    returnData.Add("error", "TimeOver");
                }
                else if (lc_www.error == null)
                {
                    //				Debug.Log("no error");
                    Debug.Log("Server Says : " + lc_www.text);
                    returnData = ParsingServerData(lc_www.text, bodProtocol);
                }
                else if (lc_www.error != null)
                {
                    Debug.Log("Error! : " + lc_www.error + "\n" + lc_www.url);

                    if (lc_www.responseHeaders.ContainsKey("STATUS"))
                        Debug.Log("Error! : " + lc_www.responseHeaders["STATUS"].ToString());
                    returnData.Add("error", lc_www.error.ToString());
                }
                break;
            default:
                break;
        }


        if (!returnData.ContainsKey("error"))
        {
            callback(returnData);
        }
        else
        {
            Debug.LogError("Rest Error! - " + returnData["error"].ToString());
            string[] param = new string[2];
            param[0] = url;
            param[1] = lc_www.Status.ToString();
            MessagePopup.window.ShowPopup(MESSAGEPOPUPTYPE.WebServerException, param, MessagePopupCallback);
        }
    }

    private Hashtable ParsingServerData(string returnString, RestAPIProtocol bodProtocol)
    {
        Hashtable returnData = new Hashtable();

        if (returnString.Contains("{") || returnString.Contains("["))
        {
            //glog.debug("RETURN STR -- " + returnString);
            //          JsonData data = JsonMapper.ToObject(returnString);

            ArrayList jsonArray = new ArrayList();
            Hashtable jsonTable = new Hashtable();

            if (returnString.IndexOf("[") == 0)
                jsonArray = JSON.JsonDecode(returnString) as ArrayList;
            else
                jsonTable = JSON.JsonDecode(returnString) as Hashtable;

            //for (int i = 0; i < data.Count; i++)
            //{
            //    glog.debug("JSON Data [" + i + "] -- " + data);
            //    glog.debug("JSON Type [" + i + "] -- " + data.GetJsonType());
            //}

            switch (bodProtocol)
            {
                case RestAPIProtocol.CREATEUSER:
                    break;
                case RestAPIProtocol.GETNORMALGACHAINFO:
                case RestAPIProtocol.GETCASHGACHAINFO:
                    if (jsonTable.ContainsKey("UnitId") && !string.IsNullOrEmpty(jsonTable["UnitId"].ToString()))
                        returnData.Add("UnitId", jsonTable["UnitId"]);
                    break;
                case RestAPIProtocol.GETMYUNITLIST:
                    //temporary, must be modified. By HyunSeung(13.09.26)
                    MyInfo.Instance.MyUnitsList.Clear();
                    for (int i = 0; i < jsonArray.Count; i++)
                    {
                        Hashtable data = jsonArray[i] as Hashtable;
                        int dbId = int.Parse(data["Id"].ToString());
                        int classId = int.Parse(data["UnitId"].ToString());
                        int exp = int.Parse(data["Exp"].ToString());
                        int level = int.Parse(data["Level"].ToString());
                        int grade = int.Parse(data["Grade"].ToString());
                        MyInfo.Instance.MyUnitsList.Add(new UnitInfo(dbId, classId, level, exp, grade));
                    }
                    break;
                case RestAPIProtocol.SENDUNITCOMPOSERESULT:
                case RestAPIProtocol.SENDUNITEVOLUTIONRESULT:
                    bool isExistUnit = false;
                    for (int i = 0; i < MyInfo.Instance.MyUnitsList.Count; i++)
                    {
                        if (MyInfo.Instance.MyUnitsList[i].UnitDBID == int.Parse(jsonTable["Id"].ToString()))
                        {
                            MyInfo.Instance.MyUnitsList[i].exp = int.Parse(jsonTable["Exp"].ToString());
                            MyInfo.Instance.MyUnitsList[i].UnitLevel = int.Parse(jsonTable["Level"].ToString());
                            isExistUnit = true;
                        }
                    }
                    if (!isExistUnit)
                    {
                        returnData.Add("NewUnitClassId", jsonTable["UnitId"].ToString());
                    }
                    break;
                case RestAPIProtocol.BUYSHOPITEM:
                    returnData.Add("isSuccess", (bool)jsonTable["Result"]);
                    break;
                case RestAPIProtocol.GETUSERRANKINGLIST:
                    List<RankingInfo> infoList = new List<RankingInfo>();
                    for (int i = 0; i < jsonArray.Count; i++)
                    {
                        Hashtable data = jsonArray[i] as Hashtable;
                        int id = int.Parse(data["Id"].ToString());
                        int userId = int.Parse(data["UserId"].ToString());
                        string userName = data["Name"].ToString();
                        int totalBattleCount = int.Parse(data["GameCount"].ToString());
                        int winCount = int.Parse(data["Win"].ToString());
                        int retireCount = int.Parse(data["Retire"].ToString());
                        int score = int.Parse(data["Score"].ToString());
                        int pawn = int.Parse(data["Pawn"].ToString());
                        infoList.Add(new RankingInfo(id, userId, userName, totalBattleCount, winCount, retireCount, score, pawn));
                    }

                    returnData.Add("list", infoList);
                    break;
                case RestAPIProtocol.REFRESHUSERINFO:
                    MyInfo.Instance.DBID = int.Parse(jsonTable["Id"].ToString());
                    MyInfo.Instance.NickName = jsonTable["Name"].ToString();
                    MyInfo.Instance.userLevel = int.Parse(jsonTable["Level"].ToString());
                    MyInfo.Instance.Exp = Int64.Parse(jsonTable["Exp"].ToString());
                    MyInfo.Instance.Score = int.Parse(jsonTable["Score"].ToString());
                    MyInfo.Instance.HPPotion = int.Parse(jsonTable["HpPotion"].ToString());
                    MyInfo.Instance.ResurrectPotion = int.Parse(jsonTable["ResurrectPotion"].ToString());
                    MyInfo.Instance.Money = int.Parse(jsonTable["Money"].ToString());
                    //MyInfo.Instance.Stamina = int.Parse(jsonTable["Stamina"].ToString());
                    MyInfo.Instance.Diamond = int.Parse(jsonTable["Diamond"].ToString());
                    MyInfo.Instance.AdditionalInvenCount = int.Parse(jsonTable["InventoryExtend"].ToString());
                    MyInfo.Instance.LastLoginTime = jsonTable["LastLogin"].ToString();
                    MyInfo.Instance.leaderClassId = int.Parse(jsonTable["Leader"].ToString());
                    MyInfo.Instance.pawnId = int.Parse(jsonTable["Pawn"].ToString());
                    MyInfo.Instance.gachaPoint = int.Parse(jsonTable["GachaPoint"].ToString());
                    MyInfo.Instance.gachaTicket = int.Parse(jsonTable["GachaTicket"].ToString());
                    break;
                case RestAPIProtocol.REFRESHMYDECKINFO:
                    MyInfo.Instance.MyDeckMap.Clear();
                    //temporary const.
                    MyInfo.Instance.MyCurrentDeck = -1;

                    DeckInfo tmpDeckInfo = new DeckInfo();

                    for (int i = 0; i < jsonArray.Count; i++)
                    {
                        Hashtable data = jsonArray[i] as Hashtable;
                        tmpDeckInfo = new DeckInfo();
                        int SlotUID = int.Parse(data["Id"].ToString());
                        int UserDBID = int.Parse(data["UserId"].ToString());
                        int orderId = int.Parse(data["Order"].ToString());
                        int skill1 = int.Parse(data["Skill1"].ToString());
                        int skill2 = int.Parse(data["Skill2"].ToString());

                        tmpDeckInfo.deckId = SlotUID;
                        tmpDeckInfo.order = orderId;
                        tmpDeckInfo.skill1 = skill1;
                        tmpDeckInfo.skill2 = skill2;

                        if (UserDBID == MyInfo.Instance.DBID)
                        {
                            //MyInfo.Instance.MyCurrentDeckDBID = SlotUID;
                            if (data["Leader"] != null)
                            {
                                int tempUnitId = int.Parse(data["Leader"].ToString());
                                UnitInfo tmpUnit = new UnitInfo(0, 0, 0, 0, 0);
                                if (tempUnitId != 0)
                                {
                                    UnitInfo info = MyInfo.Instance.GetUnitInfoById(tempUnitId);
                                    tmpUnit = new UnitInfo(info.UnitDBID, info.UnitClassID, info.UnitLevel, info.exp);
                                }
                                tmpDeckInfo.AddUnitInfo(0, tmpUnit);
                            }

                            if (data["Sub1"] != null)
                            {
                                int tempUnitId = int.Parse(data["Sub1"].ToString());
                                UnitInfo tmpUnit = new UnitInfo(0, 0, 0, 0, 0);
                                if (tempUnitId != 0)
                                {
                                    UnitInfo info = MyInfo.Instance.GetUnitInfoById(tempUnitId);
                                    tmpUnit = new UnitInfo(info.UnitDBID, info.UnitClassID, info.UnitLevel, info.exp);
                                }
                                tmpDeckInfo.AddUnitInfo(1, tmpUnit);
                            }

                            if (data["Sub2"] != null)
                            {
                                int tempUnitId = int.Parse(data["Sub2"].ToString());
                                UnitInfo tmpUnit = new UnitInfo(0, 0, 0, 0, 0);
                                if (tempUnitId != 0)
                                {
                                    UnitInfo info = MyInfo.Instance.GetUnitInfoById(tempUnitId);
                                    tmpUnit = new UnitInfo(info.UnitDBID, info.UnitClassID, info.UnitLevel, info.exp);
                                }
                                tmpDeckInfo.AddUnitInfo(2, tmpUnit);
                            }

                            if (data["Sub3"] != null)
                            {
                                int tempUnitId = int.Parse(data["Sub3"].ToString());
                                UnitInfo tmpUnit = new UnitInfo(0, 0, 0, 0, 0);
                                if (tempUnitId != 0)
                                {
                                    UnitInfo info = MyInfo.Instance.GetUnitInfoById(tempUnitId);
                                    tmpUnit = new UnitInfo(info.UnitDBID, info.UnitClassID, info.UnitLevel, info.exp);
                                }
                                tmpDeckInfo.AddUnitInfo(3, tmpUnit);
                            }

                            if (data["Sub4"] != null)
                            {
                                int tempUnitId = int.Parse(data["Sub4"].ToString());
                                UnitInfo tmpUnit = new UnitInfo(0, 0, 0, 0, 0);
                                if (tempUnitId != 0)
                                {
                                    UnitInfo info = MyInfo.Instance.GetUnitInfoById(tempUnitId);
                                    tmpUnit = new UnitInfo(info.UnitDBID, info.UnitClassID, info.UnitLevel, info.exp);
                                }
                                tmpDeckInfo.AddUnitInfo(4, tmpUnit);
                            }

                            MyInfo.Instance.MyDeckMap.Add(i, tmpDeckInfo);
                        }

                        for (int j = 0; j < MyInfo.Instance.MyDeckMap.Count; j++)
                        {
                            for (int k = 0; k < MyInfo.Instance.MyDeckMap.Count - j - 1; k++)
                            {
                                if (MyInfo.Instance.MyDeckMap[k].deckId > MyInfo.Instance.MyDeckMap[k + 1].deckId)
                                {
                                    DeckInfo tempDeckInfo = MyInfo.Instance.MyDeckMap[k];
                                    MyInfo.Instance.MyDeckMap[k] = MyInfo.Instance.MyDeckMap[k + 1];
                                    MyInfo.Instance.MyDeckMap[k + 1] = tempDeckInfo;
                                }
                            }
                        }
                    }
                    break;
                case RestAPIProtocol.SENDFACEBOOKINFO:
                    CSceneManager.manager.GoToLoadingScene();
                    break;
                case RestAPIProtocol.SENDMYDECKCHANGEINFO:
                    break;
                case RestAPIProtocol.GETMYFRIENDLIST:
                    MyInfo.Instance.MyFriendList.Clear();

                    for (int i = 0; i < jsonArray.Count; i++)
                    {
                        Hashtable data = jsonArray[i] as Hashtable;
                        int userID = int.Parse(data["UserId"].ToString());
                        int classId = int.Parse(data["Pawn"].ToString());
                        int level = int.Parse(data["Level"].ToString());
                        string name = "";
                        if (!string.IsNullOrEmpty(data["Name"].ToString()))
                            name = data["Name"].ToString();
                        string time = data["LastLogin"].ToString();
                        int skill1 = int.Parse(data["Skill1"].ToString());
                        int skill2 = int.Parse(data["Skill2"].ToString());

                        MyInfo.Instance.MyFriendList.Add(new FriendInfo(userID, classId, level, name, time, skill1, skill2));
                    }
                    break;
                case RestAPIProtocol.GETMYFRIENDREQUESTLIST:
                    MyInfo.Instance.MyFriendRequestedList.Clear();

                    for (int i = 0; i < jsonArray.Count; i++)
                    {
                        Hashtable data = jsonArray[i] as Hashtable;
                        int userID = int.Parse(data["UserId"].ToString());
                        int classId = int.Parse(data["Pawn"].ToString());
                        int level = int.Parse(data["Level"].ToString());
                        string name = data["Name"].ToString();
                        string time = data["LastLogin"].ToString();
                        int skill1 = int.Parse(data["Skill1"].ToString());
                        int skill2 = int.Parse(data["Skill2"].ToString());

                        MyInfo.Instance.MyFriendRequestedList.Add(new FriendInfo(userID, classId, level, name, time, skill1, skill2));
                    }
                    break;
                case RestAPIProtocol.GETMYMAILBOXLIST:
                    for (int i = 0; i < jsonArray.Count; i++)
                    {
                        Hashtable data = jsonArray[i] as Hashtable;
                        int id = int.Parse(data["Id"].ToString());
                        int senderType = int.Parse(data["SenderType"].ToString());
                        int attachType = int.Parse(data["AttachType"].ToString());
                        int attachId = int.Parse(data["AttachId"].ToString());
                        int attachAmount = int.Parse(data["AttachAmount"].ToString());
                        string name = data["Name"].ToString();
                        string title = data["Title"].ToString();
                        Debug.LogError(title);
                        string time = data["Date"].ToString();

                        MyInfo.Instance.MyMailboxList.Add(new MailInfo(id, name, title, senderType, attachType, attachId, attachAmount, time));
                    }
                    break;
                case RestAPIProtocol.SENDFACEBOOKAPPREQUESTINFO:
                    break;
                case RestAPIProtocol.GETCURRENTSTAMINAINFO:
                    MyInfo.Instance.Stamina = int.Parse(jsonTable["Current"].ToString());
                    MyInfo.Instance.MaxStamina = int.Parse(jsonTable["Maximum"].ToString());
                    MyInfo.Instance.NextTickTimeForStamina = DateTime.Parse(jsonTable["NextRegenTime"].ToString());
                    MyInfo.Instance.NextTickSecondForStamina = double.Parse(jsonTable["NextRegenSecond"].ToString());
                    break;
                case RestAPIProtocol.SELLUNITCARD:
                    MyInfo.Instance.Money = int.Parse(jsonTable["userMoney"].ToString());
                    break;
                case RestAPIProtocol.GETMYSKILLLIST:
                    MyInfo.Instance.MySkillList.Clear();
                    for (int i = 0; i < jsonArray.Count; i++)
                    {
                        Hashtable data = jsonArray[i] as Hashtable;
                        if (data["SkillId"] != null && data["SkillId"].ToString() != "")
                        {
                            if (!MyInfo.Instance.MySkillList.Contains(int.Parse(data["SkillId"].ToString())))
                                MyInfo.Instance.MySkillList.Add(int.Parse(data["SkillId"].ToString()));
                        }
                    }
                    break;
                case RestAPIProtocol.GETMYCHARACTERLIST:
                    for (int i = 0; i < jsonArray.Count; i++)
                    {
                        Hashtable data = jsonArray[i] as Hashtable;
                        if (data["CharacterId"] != null && data["CharacterId"].ToString() != "")
                        {
                            if (!MyInfo.Instance.MyCharacterList.Contains(int.Parse(data["CharacterId"].ToString())))
                                MyInfo.Instance.MyCharacterList.Add(int.Parse(data["CharacterId"].ToString()));
                        }
                    }
                    break;
                case RestAPIProtocol.SETCURRENTCHARACTER:
                    break;
                case RestAPIProtocol.SENDDEVICEPUSHTOKEN:
                    break;
                case RestAPIProtocol.GETMYACHIEVEMENTLIST:
                    MyInfo.Instance.AchievementList.Clear();

                    for (int i = 0; i < jsonArray.Count; i++)
                    {
                        Hashtable data = jsonArray[i] as Hashtable;
                        AchievementInfo achievement = new AchievementInfo();
                        achievement.achievementId = int.Parse(data["AchievementId"].ToString());
                        achievement.achievementLevel = int.Parse(data["AchieveLevel"].ToString());
                        achievement.updateTime = DateTime.Parse(data["UpdateTime"].ToString());
                        achievement.isReward = bool.Parse(data["Reward"].ToString());
                        MyInfo.Instance.AchievementList.Add(achievement);
                    }
                    break;
                case RestAPIProtocol.GETMYACHIEVEMENTREWARD:
                    break;

                case RestAPIProtocol.GETMYACHIEVEMENTVALUE:
                    for (int i = 0; i < jsonArray.Count; i++)
                    {
                        Hashtable data = jsonArray[i] as Hashtable;
                        AchievementValue achievement = new AchievementValue();
                        achievement.achievementLogname = int.Parse(data["ValueId"].ToString());
                        achievement.achievementData = int.Parse(data["Data"].ToString());
                        MyInfo.Instance.AchievementValueList.Add(achievement);
                    }
                    break;
                case RestAPIProtocol.GETPVESTAGEINFO:
                    {
                        if (jsonTable != null && jsonTable["StageInfo"] != null)
                        {
                            Hashtable data = JSON.JsonDecode(jsonTable["StageInfo"].ToString()) as Hashtable;

                            if (data != null && data["PVEStage"] != null)
                            {
                                MyInfo.Instance.MyPVEStageInfo.StoryMode = Int32.Parse(data["PVEStage"].ToString());
                            }
                            else
                            {
                                Debug.LogError("PVEStage is null");
                            }

                            if (data != null && data["ClearList"] != null)
                            {
                                ArrayList list = data["ClearList"] as ArrayList;

                                for (int i = 0; i < list.Count; i++)
                                {
                                    MyInfo.Instance.MyPVEStageInfo.EventMode.Add((int)list[i]);
                                }
                            }
                            else
                            {
                                Debug.LogError("ClearList is null");
                            }
                        }
                        else
                        {
                            Debug.LogError("StageInfo is null");
                        }
                    }
                    break;
                default:
                    break;
            }
        }
        else
        {
            returnData.Add("json", "Datatype is not json");
        }

        returnData.Add("protocol", bodProtocol);

        return returnData;
    }

    public void MessagePopupCallback(MESSAGEPOPUPTYPE type, bool isYes)
    {
        if (type == MESSAGEPOPUPTYPE.DISCONNECT || type == MESSAGEPOPUPTYPE.SERVERERROR)
        {
            //			LoadingSceneManager.isForcedReLogin = true;
            CSceneManager.LoginSuccess = false;
            CSceneManager.VersionCheckSuccess = false;
            CSceneManager.manager.GoToLoadingScene();
        }
    }

    #region Static Function
    public static DateTime ConvertFromUnixTimestamp(double timestamp)
    {
        DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Unspecified);
        return origin.AddSeconds(timestamp);
    }

    public static double ConvertToUnixTimestamp(DateTime date)
    {
        DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0);
        return (date - origin).TotalSeconds;
    }
    string UTF8Encoiding(string target)
    {
        byte[] utf8Bytes = Encoding.UTF8.GetBytes(target);
        return Encoding.UTF8.GetString(utf8Bytes);
    }
    #endregion
}